package jdbc;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

public class BaseDao<T> {
	private Class<T> classt;
	private String tableName;
	private Field[] field;

	@SuppressWarnings("unchecked")
	public BaseDao() {
		ParameterizedType tp = (ParameterizedType) this.getClass().getGenericSuperclass();
		// 反射获得泛型参数：getGenericSuperclass 返回类：getclass
		classt = (Class<T>) tp.getActualTypeArguments()[0];
		tableName = classt.getSimpleName();
		field = classt.getDeclaredFields();
	}

	public void deleteSome(Object id) {
		StringBuffer sql = new StringBuffer("delete from" + " ");
		// 设定语句
		sql.append(tableName + " ");
		sql.append("where");
		// 将语句中加入条件

		field[0].setAccessible(true);
		sql = sql.append(" " + field[0].getName() + "=?");
		try {
			Connection con = Util.getCon();
			PreparedStatement pstm = con.prepareStatement(sql.toString());
			pstm.setObject(1, id);
			System.out.println(sql);
			pstm.executeUpdate();
		} catch (Exception ex) {

			ex.printStackTrace();
		}
	}

	public List<T> findBySql(String sql) {
		System.out.println("basedao:"+sql);
		List<T> list = new ArrayList<>();
		// 建立泛型集合
		Connection con = Util.getCon();
		// 建立连接
		try {
			Statement stm = con.createStatement();
			// 创建新的声明
			ResultSet rs = stm.executeQuery(sql);
			// 将语句传入数据库并做结果集
			while (rs.next()) {
				// 结果集遍历
				T t = classt.newInstance();
				for (int i = 0; i < field.length; i++) {
					// 列名循环
					field[i].setAccessible(true);
					// 设定为可访问的
					Object fv = rs.getObject(i + 1);
					// 集合末尾存入fv

					if (fv instanceof BigDecimal) {
						// 与bigdecimal做比较
						BigDecimal bd = (BigDecimal) fv;
						// 将fv转换成bigdecimal并存入bd
						switch (field[i].getType().getSimpleName()) {
						// 返回集合的类型和简名
						case "int":
						case "Integer":
							// 对应整数型的话
							fv = bd.intValue();
							// 将bd转换
							break;
						case "double":
						case "Double":
							fv = bd.doubleValue();
							break;
						}
					}
					field[i].set(t, fv);
					// 将t fv放置集合内
				}
				list.add(t);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return list;
	}

	public List<T> findAll() {
		return findBySql("select * from " + tableName);
	}

	public void insert(T o) {

		StringBuffer sql = new StringBuffer("insert into" + " ");
		sql.append(tableName);
		sql.append("(");
		int n = 0;
		try {
			for (int i = 0; i < field.length; i++) {

				field[i].setAccessible(true);
				Object val = field[i].get(o);
				if (val != null) {
					sql = sql.append(field[i].getName()).append(",");
					n++;
				}
			}
			Object[] val = new Object[n];
			sql.replace(sql.length() - 1, sql.length(), ")");
			sql.append("values(");
			int j = 0;
			for (int i = 0; i < field.length; i++) {
				field[i].setAccessible(true);
				Object ov = field[i].get(o);
				if (ov != null) {
					sql.append("?");
					val[j++] = ov;
				}
			}

			sql.replace(sql.length() - 1, sql.length(), ")");
			System.out.println(sql.toString());
			Connection con = Util.getCon();
			PreparedStatement pstm = con.prepareStatement(sql.toString());
			for (int i = 0; i < n; i++) {
				pstm.setObject(i + 1, val[i]);
			}
			pstm.executeUpdate();
		} catch (Exception e) {

			e.printStackTrace();
		}
	}

	public void update(T o) {
		StringBuffer sql = new StringBuffer("update");
		sql.append(" " + tableName);
		sql.append(" set");

		try {
			for (int i = 0; i < field.length; i++) {
				field[i].setAccessible(true);
				Object ob = field[i].get(o);
				if (ob != null) {
					sql = sql.append(field[i].getName() + "='").append(ob + ",");
				}

			}
			sql = sql.replace(sql.length() - 1, sql.length(), " ");
			field[0].setAccessible(true);
			System.out.println(sql.toString());
			Object ob = field[0].get(o);
			sql = sql.append("where " + field[0].getName() + "=" + ob);
			System.out.println(sql.toString());
		} catch (IllegalArgumentException | IllegalAccessException e) {

			e.printStackTrace();
		}

		Connection con = Util.getCon();
		try {
			PreparedStatement pstm = con.prepareStatement(sql.toString());
			pstm.executeUpdate();
		} catch (SQLException e) {

			e.printStackTrace();
		}
		
	}
	public List<T> inout(T o){
		List<T> list = new ArrayList<>();
		StringBuffer sql = new StringBuffer("select * from");
		sql.append(tableName+" where");
		sql.append(field[8]+">");
		try {
			Object obj = field[8].get(o);
			if(obj!=null){
				sql=sql.append("(select *round(avg("+field[8]+"))").append(" from");
				
			}
			sql=sql.append(tableName).append(" where");
			Object ob = field[11].get(o);
			if(ob!=null){
				sql=sql.append(ob+"="+ob+")");
			}
			System.out.println(sql.toString());
			Connection con = Util.getCon();
			PreparedStatement pstm = con.prepareStatement(sql.toString());
			ResultSet rs = pstm.executeQuery();
		} catch (Exception e) {
			
			e.printStackTrace();
		} 
		return list;
		
	}
}
